
#include <string.h>
#include "../lib/sw_pwm.h"
#include "../lib/byte_bit.h"

#define IDLE_LEVLE		1
#define PULSE_LEVLE		!IDLE_LEVLE


#define SEND_BIT_0			0
#define SEND_BIT_1			1
#define SEND_BIT_SYNC		2
#define SEND_BIT_END		3
#define SEND_BIT_ERROR		4

#define IR_TICK_TIME_IN_US			40UL						//50us/tick

#define SYNC_PULSE_TIME_TICK		6000/IR_TICK_TIME_IN_US
#define SYNC_IDLE_TIME_TICK			7320/IR_TICK_TIME_IN_US

#define BIT0_PULSE_TIME_TICK		530/IR_TICK_TIME_IN_US
#define BIT0_IDLE_TIME_TICK			(2000-530)/IR_TICK_TIME_IN_US

#define BIT1_PULSE_TIME_TICK		530/IR_TICK_TIME_IN_US
#define BIT1_IDLE_TIME_TICK			(4000-530)/IR_TICK_TIME_IN_US

#define END_PULSE_TIME_TICK			530/IR_TICK_TIME_IN_US
#define END_IDLE_TIME_TICK			(8000-530)/IR_TICK_TIME_IN_US

/*
#define SYNC_PULSE_TIME_TICK		9000/IR_TICK_TIME_IN_US		//9000us,
#define SYNC_IDLE_TIME_TICK			4500/IR_TICK_TIME_IN_US

#define BIT0_PULSE_TIME_TICK		560/IR_TICK_TIME_IN_US
#define BIT0_IDLE_TIME_TICK			560/IR_TICK_TIME_IN_US

#define BIT1_PULSE_TIME_TICK		560/IR_TICK_TIME_IN_US
#define BIT1_IDLE_TIME_TICK			1690/IR_TICK_TIME_IN_US

#define END_PULSE_TIME_TICK			560/IR_TICK_TIME_IN_US
#define END_IDLE_TIME_TICK			10000/IR_TICK_TIME_IN_US	//40ms
*/

static SW_PWM_STRUCT ir_sender;
static uint8_t send_buffer[16] = {0};
static uint8_t send_buffer_len = 0;
static uint8_t send_bit_count = 0;
static uint8_t send_byte_count = 0;
static uint8_t sender_busy_falg = 0;

void pwm_test(void)
{
	sw_pwm_set_period(&ir_sender, 2);//BIT0_PULSE_TIME_TICK+BIT0_IDLE_TIME_TICK);
	sw_pwm_set_compare_2(&ir_sender, 1);//BIT0_PULSE_TIME_TICK);
	sw_pwm_enable(&ir_sender);
}

void pwm_test_tick(void)
{
	sw_pwm_tick_handler(&ir_sender, 1);
}

static void send_bit(uint8_t bit_type)
{
	switch(bit_type){
		case SEND_BIT_0:
		sw_pwm_set_period(&ir_sender, BIT0_PULSE_TIME_TICK+BIT0_IDLE_TIME_TICK);
		sw_pwm_set_compare_2(&ir_sender, BIT0_PULSE_TIME_TICK);
		break;
		case SEND_BIT_1:
		sw_pwm_set_period(&ir_sender, BIT1_PULSE_TIME_TICK+BIT1_IDLE_TIME_TICK);
		sw_pwm_set_compare_2(&ir_sender, BIT1_PULSE_TIME_TICK);
		break;
		case SEND_BIT_SYNC:
		sw_pwm_set_period(&ir_sender, SYNC_PULSE_TIME_TICK+SYNC_IDLE_TIME_TICK);
		sw_pwm_set_compare_2(&ir_sender, SYNC_PULSE_TIME_TICK);
		break;
		case SEND_BIT_END:
		sw_pwm_set_period(&ir_sender, END_PULSE_TIME_TICK+END_IDLE_TIME_TICK);
		sw_pwm_set_compare_2(&ir_sender, END_PULSE_TIME_TICK);
		break;
		default:
		break;
	}
}

static void send_bit_finish_callback_handler(void* p)
{
	uint8_t t_bit;
	if(send_byte_count == send_buffer_len){
		send_byte_count++;
		t_bit = SEND_BIT_END;
	}
	else if(send_byte_count > send_buffer_len){
		sender_busy_falg = 0;
		sw_pwm_disable(&ir_sender);
		return;
	}
	else{
		if(byte_to_bit_lsb_frist(&t_bit, &send_bit_count, send_buffer[send_byte_count]) == 0){
			send_byte_count++;
		}
	}
	send_bit(t_bit);
	sw_pwm_reset_timeout(&ir_sender);
}


uint8_t bsp_ir_send(uint8_t* send_data, uint8_t send_data_len)
{
	if((sender_busy_falg == 0)&&(send_data_len <= 16)){
		memcpy(send_buffer, send_data, send_data_len);
		send_buffer_len = send_data_len;
		send_bit_count = 0;
		send_byte_count = 0;
		sender_busy_falg = 1;
		send_bit(SEND_BIT_SYNC);
		sw_pwm_enable(&ir_sender);
		return 1;
	}
	else{
		return 0;
	}
}

void bsp_ir_send_tick_handler(void)
{
	if(sender_busy_falg == 0){
		return;
	}
	sw_pwm_tick_handler(&ir_sender, 1);
}

void bsp_ir_send_init(void (*bsp_ir_send_hal_init_callbakc_handler)(void),
						void (*bsp_ir_send_hal_set_level_pulse_callbakc_handler)(void),
						void (*bsp_ir_send_hal_set_level_idle_callbakc_handler)(void))
{
	if(bsp_ir_send_hal_init_callbakc_handler != 0){
		bsp_ir_send_hal_init_callbakc_handler();
	}
	
	send_buffer_len = 0;
	send_bit_count = 0;
	send_byte_count = 0;
	sender_busy_falg = 0;

	sw_pwm_init(&ir_sender, 
				0, 0, 0, IDLE_LEVLE,
//				send_bit_finish_callback_handler, 
				0,
				bsp_ir_send_hal_set_level_idle_callbakc_handler,
				bsp_ir_send_hal_set_level_pulse_callbakc_handler,
				0, 0);
}